package com.winit.schedule.job.tracker.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.winit.schedule.job.tracker.util.RequestUtils;
import com.winit.schedule.job.tracker.web.controller.OpenController;
import com.winit.schedule.job.tracker.web.controller.UserController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.alibaba.fastjson.JSON;
import com.winit.schedule.core.utils.StringUtils;
import com.winit.schedule.job.tracker.JobTracker;
import com.winit.schedule.job.tracker.util.Constants;
import com.winit.schedule.job.tracker.web.auth.User;
import com.winit.schedule.job.tracker.web.controller.JobController;
import com.winit.schedule.webc.annotation.ResponseType;
import com.winit.schedule.webc.exception.ScheduleWebcException;
import com.winit.schedule.webc.support.Response;
import com.winit.schedule.webc.support.ScheduleRequestInterceptor;

public class UScheduleServlet extends HttpServlet {

    private final static Logger        logger = LoggerFactory.getLogger(UScheduleServlet.class);

    private JobController              jobController;

    private ScheduleRequestInterceptor interceptor;

    @Override
    public void init() throws ServletException {

    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
        JobTracker jobTracker = (JobTracker) context.getBean("jobTracker");
        jobController = JobController.getInstance(jobTracker.getJobTrackerContext());

        interceptor = new ScheduleRequestInterceptor();
        interceptor.registerController(jobController);

        OpenController openController = OpenController.getInstance(jobTracker.getJobTrackerContext());
        interceptor.registerController(openController);

        UserController userController = UserController.getInstance(jobTracker.getJobTrackerContext());
        interceptor.registerController(userController);
    }

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = -7592730583978014940L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");

        String cmd = req.getParameter("cmd");
        String namespace = interceptor.getNamespace(req);
        if (HttpCommand.LOGIN.getCode().equals(cmd) || HttpCommand.LOGOUT.getCode().equals(cmd) || OpenController.NAMESPACE.equals(namespace)) {
            interceptor(req, resp);
        } else {

            User user = (User) req.getSession().getAttribute(Constants.SESSION_USERINFO);

            if (null == user) {
                resp.sendRedirect(req.getContextPath());
            } else {
                RequestUtils.setLoginUser(user);
                if (StringUtils.isBlank(cmd)) {
                    req.getRequestDispatcher("home.jsp").forward(req, resp);
                } else {
                    interceptor(req, resp);
                }
                RequestUtils.setLoginUser(null);
            }
        }
    }

    private void interceptor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Response response = null;
        try {
            response = interceptor.interceptor(req, resp);
        } catch (IllegalArgumentException e) {
            logger.error("Parameter error", e);
            throw new ScheduleWebcException("Parameter error", e);
        } catch (IllegalAccessException e) {
            logger.error("Unable to access requests", e);
            throw new ScheduleWebcException("Unable to access requests", e);
        } catch (InvocationTargetException e) {
            logger.error("Unable to find the requested corresponding controller", e);
            throw new ScheduleWebcException("Unable to find the requested corresponding controller", e);
        }
        if (ResponseType.FORWARD.equals(response.getResponseType())) {
            req.getRequestDispatcher(response.getValue().toString()).forward(req, resp);
        } else if (ResponseType.REDIRECT.equals(response.getResponseType())) {

        } else {
            responseToJson(resp, response.getValue());
        }
    }

    private void responseToJson(HttpServletResponse resp, Object object) {
        resp.setContentType("application/json;charset=utf-8");
        resp.setDateHeader("expries", -1);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("Pragma", "no-cache");
        PrintWriter out = null;
        try {
            out = resp.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.print(JSON.toJSONString(object));
        out.close();
    }

}
